/*
 * Copyright (C) 2010 Fred Barrie This program is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received
 * a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.aergia.vinny.database.pojo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

import org.w3c.dom.Element;

/**
 * @author fred
 */
@Entity
public class VinnyUser implements DatabasePojo {

	private boolean active;
	private String firstName;
	private int id;
	private String lastName;
	private Location location;
	private String password;
	private Collection<VinnyRole> roles;
	private String userName;

	public VinnyUser() {
		this.roles = new ArrayList<VinnyRole>();
	}

	/**
	 * @param userName
	 */
	public VinnyUser(final String userName) {
		this.userName = userName;
		this.active = true;
		this.roles = new ArrayList<VinnyRole>();
	}

	/**
	 * @param userName
	 * @param modifyService
	 */
	public VinnyUser(final String userName, final String role) {
		this.userName = userName;
		this.active = true;
		final VinnyRole vinnyRole = new VinnyRole(role);
		this.roles = Collections.singleton(vinnyRole);
	}

	/**
	 * @param userName
	 * @param modifyService
	 */
	public VinnyUser(final String userName, final VinnyRole role) {
		this.userName = userName;
		this.active = true;
		this.roles = Collections.singleton(role);
	}

	@Override
	public void attachAttributes(final Element element) {
		element.setAttribute("id", Integer.toString(this.getId()));
		element.setAttribute("active", Boolean.toString(this.isActive()));

		if (this.getFirstName() != null) {
			element.setAttribute("firstName", this.getFirstName());
		}

		if (this.getLastName() != null) {
			element.setAttribute("lastName", this.getLastName());
		}

		element.setAttribute("location", Integer.toString(this.getLocation().getId()));
		element.setAttribute("password", this.getPassword());

		final Element roleListElement = element.getOwnerDocument().createElement("Role-List");
		element.appendChild(roleListElement);

		for (final VinnyRole role : this.getRoles()) {
			final Element roleElement = element.getOwnerDocument().createElement("Role");
			roleListElement.appendChild(roleElement);
			roleElement.setAttribute("role-id", Integer.toString(role.getId()));
		}

		element.setAttribute("userName", this.getUserName());
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof VinnyUser)) {
			return false;
		}
		final VinnyUser other = (VinnyUser) obj;
		if (this.getUserName() == null) {
			if (other.getUserName() != null) {
				return false;
			}
		} else if (!this.getUserName().equals(other.getUserName())) {
			return false;
		}
		return true;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return this.firstName;
	}

	@Override
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public int getId() {
		return this.id;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return this.lastName;
	}

	/**
	 * @return the location
	 */
	@ManyToOne
	public Location getLocation() {
		return this.location;
	}

	public String getName() {
		if ((this.getFirstName() == null) && (this.getLastName() == null)) {
			return this.getUserName();
		}
		return this.getFirstName() != null ? this.getFirstName() : "" + " " + this.getLastName() != null ? this.getLastName() : "";
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return this.password;
	}

	/**
	 * @return the roles
	 */
	@ManyToMany
	public Collection<VinnyRole> getRoles() {
		return this.roles;
	}

	/**
	 * @return the userName
	 */
	public String getUserName() {
		return this.userName;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (this.getUserName() == null ? 0 : this.getUserName().hashCode());
		return result;
	}

	/**
	 * @param string
	 * @return
	 */
	public boolean inRole(final String permission) {
		for (final VinnyRole role : this.getRoles()) {
			if (role.isActive() && role.getPermission().equals(permission)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean isActive() {
		return this.active;
	}

	/**
	 * @param active
	 *            the active to set
	 */
	public void setActive(final boolean active) {
		this.active = active;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(final String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(final int id) {
		this.id = id;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(final String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @param location
	 *            the location to set
	 */
	public void setLocation(final Location location) {
		this.location = location;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(final String password) {
		this.password = password;
	}

	/**
	 * @param roles
	 *            the roles to set
	 */
	public void setRoles(final Collection<VinnyRole> roles) {
		this.roles = roles;
	}

	/**
	 * @param userName
	 *            the userName to set
	 */
	public void setUserName(final String userName) {
		this.userName = userName;
	}

	@Override
	public String toString() {
		if ((this.getFirstName() == null) && (this.getLastName() == null)) {
			return this.getUserName();
		}
		return this.getFirstName() + " " + this.getLastName();
	}

}
